#include "StdAfx.h"
#include "MinkyMonkeyMachine.h"

#define ProtAdd(nn,dd)	(nn * (M->ProtSource[dd] & 0xF)) + (nn * 10 * (M->ProtSource[dd] >> 4))
#define ProtResult(nn)	((n / nn) % 10) | (((n / nn * 10) % 10) << 4)

CMinkyMonkeyMachine::CMinkyMonkeyMachine()
{
}

CMinkyMonkeyMachine::~CMinkyMonkeyMachine()
{
}

int CMinkyMonkeyMachine::Init()
{
CBurgerTimeMachine::Init();
MainCPU->SetUser(this);
SoundCPU->SetUser(this);
MainCPU->SetRead(ReadMainCPU);
MainCPU->SetWrite(WriteMainCPU);
//MainCPU->SetOp(CLockNChaseMachine::OpMainCPU);
return(0);
}

void CMinkyMonkeyMachine::Reset()
{
int n;

CLockNChaseMachine::Reset();
ProtStatus = 0;
ProtCommand = 0;
for(n=0;n<256;n++)
	{
	ProtAddResult[n & 3] = 0;
	ProtSource[n & 7] = 0;
	ProtDecrypt[n] = 0;
	}
}

void CMinkyMonkeyMachine::SaveState(CState *s)
{
CLockNChaseMachine::SaveState(s);
s->Write8(ProtCommand);
s->Write8(ProtStatus);
s->Write8(ProtData);
s->Write8(ProtResult);
s->Write(ProtAddResult,4);
s->Write(ProtDecrypt,256);
s->Write(ProtSource,8);
}

void CMinkyMonkeyMachine::LoadState(CState *s)
{
CLockNChaseMachine::LoadState(s);
ProtCommand = s->Read8();
ProtStatus = s->Read8();
ProtData = s->Read8();
ProtResult = s->Read8();
s->Read(ProtAddResult,4);
s->Read(ProtDecrypt,256);
s->Read(ProtSource,8);
}

u8 CMinkyMonkeyMachine::ReadMainCPU(void *user,u32 addr)
{
CMinkyMonkeyMachine *M = (CMinkyMonkeyMachine*)user;
u8 ret;

if((addr & 0xF000) == 0xB000)			//protection read
	{
	//message("protection read, $%04X\n",addr);
	switch(addr)
		{
		case 0xB000:						//status read
			ret = M->ProtStatus;
			M->ProtStatus &= ~2;
			return(M->ProtStatus);
		case 0xBE00:						//result read
			return(M->ProtResult);
		case 0xBD00:
		case 0xBD01:
		case 0xBD02:
			return(M->ProtAddResult[addr & 3]);
		default:
			message("bad protection read, addr = $%04X\n",addr);
			break;
		}
	}
return(CLockNChaseMachine::ReadMainCPU(user,addr));
}

void CMinkyMonkeyMachine::WriteMainCPU(void *user,u32 addr,u8 data)
{
CMinkyMonkeyMachine *M = (CMinkyMonkeyMachine*)user;

if((addr & 0xF000) == 0xB000)			//protection write
	{
	if(addr >= 0xBF00)					//decryption table
		{
		M->ProtDecrypt[addr & 0xFF] = data;
		return;
		}
/*	else if(addr >= 0xB800 && addr <= 0xB8FF)		//decryption table?
		{
		M->ProtDecrypt[addr & 0xFF] = data;
		return;
		}*/
	else
		{
		switch(addr)
			{
			case 0xB000:
				if(M->ProtCommand == 0)			//compute score
					{
					int n;
					
					n = ProtAdd(1,0) + ProtAdd(100,1) + ProtAdd(10000,2) + ProtAdd(1,3) + ProtAdd(100,4) + ProtAdd(10000,5);
					M->ProtAddResult[0] = ProtResult(1);
					M->ProtAddResult[1] = ProtResult(100);
					M->ProtAddResult[2] = ProtResult(10000);
					}
				else if(M->ProtCommand == 1)	//decrypt
					{
					int n;

					M->ProtStatus |= 2;
					for(n=0;n<256;n++)
						{
						if(M->ProtDecrypt[n] == M->ProtData)
							{
							M->ProtResult = n;
							break;
							}
						}
					}
				else
					message("bad protection command $%02X\n",M->ProtCommand);
				return;
			case 0xBC00:
				M->ProtCommand = data;
				return;
			case 0xBE00:
				M->ProtData = data;
				return;
			case 0xBD00:
			case 0xBD01:
			case 0xBD02:
			case 0xBD03:
			case 0xBD04:
			case 0xBD05:
				M->ProtSource[addr & 7] = data;
				return;
			}
		}
	message("protection write, $%04X = $%02X\n",addr,data);
	}
CLockNChaseMachine::WriteMainCPU(user,addr,data);
}
